﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace B121 {
    /// <summary>
    /// The container class
    /// </summary>
    public class ContainerClass {
        /// <summary>
        /// Creates a container
        /// </summary>
        /// <param name="name">Name of the container</param>
        /// <param name="x">X-value of the container</param>
        /// <param name="y">Y-value of the container</param>
        /// <param name="z">Z-value of the container</param>
        /// <param name="maxWeight">Maximum weight of the container</param>
        public ContainerClass(string name, int x, int y, int z, int maxWeight) {
            Name = name;
            X = x;
            Y = y;
            Z = z;
            MaxWeight = maxWeight;
            Items = new List<ItemClass>();
        }

        #region Properties
        /// <summary>
        /// Gets the name of the container
        /// </summary>
        public string Name {
            get { return _Name; }
            private set {
                if (value == null) { // Name cannot be null
                    throw new ArgumentNullException();
                } else if (value == "") { // Name cannot be empty
                    throw new ArgumentOutOfRangeException("A container cannot have an empty name");
                } else {
                    _Name = value;
                }
            }
        }
        private string _Name;

        /// <summary>
        /// Gets the X-value of the container
        /// </summary>
        public int X {
            get { return _X; }
            set {
                if (value < 1) { // Size check
                    throw new ArgumentOutOfRangeException("A container cannot have a X-value less than 1");
                } else {
                    _X = value;
                }
            }
        }
        private int _X;

        /// <summary>
        /// Gets the Y-value of the container
        /// </summary>
        public int Y {
            get { return _Y; }
            set {
                if (value < 1) { // Size check
                    throw new ArgumentOutOfRangeException("A container cannot have a Y-value less than 1");
                } else {
                    _Y = value;
                }
            }
        }
        private int _Y;

        /// <summary>
        /// Gets the Z-value of the container
        /// </summary>
        public int Z {
            get { return _Z; }
            set {
                if (value < 1) { // Size check
                    throw new ArgumentOutOfRangeException("A container cannot have a Z-value less than 1");
                } else {
                    _Z = value;
                }
            }
        }
        private int _Z;

        /// <summary>
        /// Gets the current weight of the container
        /// </summary>
        public int CurrentWeight {
            get {
                int weight = 0;
                foreach (ItemClass item in Items) { // Get weight of each item
                    weight += item.Weight;
                }
                return weight;
            }
        }

        /// <summary>
        /// Gets the max weight of the container
        /// </summary>
        public int MaxWeight {
            get { return _MaxWeight; }
            private set {
                if (value < 1) { // Weight check
                    throw new ArgumentOutOfRangeException("A container cannot have a maximum weight less than 1");
                } else {
                    _MaxWeight = value;
                }
            }
        }
        private int _MaxWeight;

        /// <summary>
        /// Gets the list of items
        /// </summary>
        public List<ItemClass> Items { get; private set; }

        /// <summary>
        /// Gets % used of containers max weight
        /// </summary>
        public double WeightUsage {
            get {
                return Math.Round((double)CurrentWeight / (double)MaxWeight * 100, 2); // Two decimals
            }
        }

        /// <summary>
        /// Gets % used of containers bottom area
        /// </summary>
        public double BottomAreaUsage {
            get {
                double areaUsed = 0, containerArea = X * Y;

                foreach (ItemClass item in Items) {
                    areaUsed += item.X * item.Y;
                }

                return Math.Round(areaUsed / containerArea * 100, 2); // Two decimals
            }
        }

        /// <summary>
        /// Gets % used of the containers volume
        /// </summary>
        public double VolumeUsage {
            get {
                double volumeUsed = 0, containerVolume = X * Y * Z;

                foreach (ItemClass item in Items) {
                    volumeUsed += item.X * item.Y * item.Z;
                }

                return Math.Round(volumeUsed / containerVolume * 100, 2); // Two decimals
            }
        }
        #endregion
    }
}
